<!-- src/lib/components/Menu/VerticalMenu.svelte -->
 <!-- src/
└── lib/
    └── components/
        └── Menu/
            ├── VerticalMenu.svelte       # 改造后的主菜单组件
            ├── VerticalMenuPopover.svelte # 改造后的弹窗菜单组件
            └── Common/                   # 公共组件目录
                ├── MenuCollapseItem.svelte # 公共折叠项组件
                ├── MenuLeafItem.svelte     # 公共叶子项组件
                └── MenuSnippet.svelte      # 公共渲染片段组件 -->
<script lang="ts">
	import { setContext, onMount } from 'svelte';
	import { goto } from '$app/navigation';
	import { page } from '$app/state';
	import Icon from '$lib/components/Basic/Icon/Icon.svelte';
	import VerticalMenuPopover from './VerticalMenuPopover.svelte';
	import Scrollbar from '$lib/components/Basic/Scrollbar/Scrollbar.svelte';
	import type { Option } from '$lib/components/Basic/Popover/types';
	import MenuSnippet from './Common/MenuSnippet.svelte';

	import { fade } from 'svelte/transition';

	// 组件核心 Props
	const {
		menuItems = [],
		isCollapsed = false,
		label = 'name',
		accordion = false
	} = $props<{
		menuItems: Option[];
		isCollapsed?: boolean;
		label?: string;
		accordion?: boolean;
	}>();

	// 拆分状态：展开状态与选中状态分离
	let levelExpandNames = $state<Record<number, string[]>>({
		1: [],
		2: [],
		3: []
	});
	let levelActiveNames = $state<Record<number, string[]>>({
		1: [],
		2: [],
		3: []
	});

	let selectedLeafId = $state<string | number | null>(null);

	// 处理层级菜单展开/折叠（仅控制显示，不影响选中状态）
	function handleLevelExpandClick(level: number, name: string, e: MouseEvent) {
		e.stopPropagation();

		if (!levelExpandNames[level]) {
			levelExpandNames[level] = [];
		}

		let next: string[];
		if (accordion) {
			next = levelExpandNames[level].includes(name) ? [] : [name];
			// 手风琴模式：关闭子层级展开状态
			Object.keys(levelExpandNames).forEach((key) => {
				const currentLevel = Number(key);
				if (currentLevel > level) {
					// 显式替换数组触发响应式更新
					levelExpandNames[currentLevel] = [...[]];
				}
			});
		} else {
			next = levelExpandNames[level].includes(name)
				? levelExpandNames[level].filter((n) => n !== name)
				: [...levelExpandNames[level], name];
		}

		// 显式创建新对象触发响应式更新
		levelExpandNames = { 
			...levelExpandNames, 
			[level]: [...next] 
		};
	}

	// 向子组件提供上下文
	setContext('vertical-menu-context', {
		getExpandNames: (level: number) => levelExpandNames[level] || [],
		getActiveNames: (level: number) => levelActiveNames[level] || [],
		handleLevelExpandClick,
		isCollapsed: () => isCollapsed
	});

	// 收缩状态下的悬浮菜单管理
	let isOpen = $state(false);
	let activeItemId = $state<string | number | null>(null);
	let activeItemIndex = $state<number>(-1);
	let triggerRefs = $state<Record<string | number, HTMLElement>>({});
	let menuContainerRef = $state<HTMLElement | null>(null);

	// 收缩状态下的点击处理
	const handleCollapsedClick = (item: Option,index:number, e: MouseEvent) => {
		e.stopPropagation();
		if (!isCollapsed) return;

		// 无子菜单则直接跳转路由
		if (!item.children || item.children.length === 0) {
			handleMenuItemClick(item, e);
			return;
		}

		// 有子菜单则显示弹窗
		isOpen = true;
		activeItemId = item.id;
		activeItemIndex = index;
	};

	const handleItemEnter = (item: Option ,index:number,e: MouseEvent) => {
		if (!isCollapsed || !isOpen) return;
		activeItemId = item.id;
		activeItemIndex = index;
	};

	const stablePath = $derived(page.url.pathname);
	let lastProcessedPath = '';

	// 监听路由变化，同步选中状态（适配 VerticalMenuPopover 的跳转）
	$effect(() => {
		if (stablePath !== lastProcessedPath) {
			initSelectedLeafByRoute(stablePath);
			lastProcessedPath = stablePath;
		}
	});

	onMount(() => {});

	// 导航跳转处理
	const handleMenuItemClick = (option: Option, e: Event) => {
		e.stopPropagation();
		selectedLeafId = option.id;
		if (option.code) {
			goto(option.code);
		} else {
			goto('/home');
		}
	};

	// 根据路由初始化选中状态和展开状态（先收缩再展开）
	const initSelectedLeafByRoute = async (currentPath: string) => {
		// 重置展开和激活状态
		levelExpandNames = { 1: [], 2: [], 3: [] };
		levelActiveNames = { 1: [], 2: [], 3: [] }; // 重置激活状态

		const findMatchedLeaf = (items: Option[]): Option | null => {
			for (const item of items) {
				if (item.children && item.children.length > 0) {
					const matched = findMatchedLeaf(item.children);
					if (matched) return matched;
				} else if (item.code === currentPath) {
					return item;
				}
			}
			return null;
		};

		const matchedItem = findMatchedLeaf(menuItems);
		if (matchedItem) {
			selectedLeafId = matchedItem.id;

			// 收集当前节点的所有上级ID（含自身）
			const collectAncestorIds = (
				items: Option[],
				targetId: string | number,
				ancestors: (string | number)[] = []
			): (string | number)[] | null => {
				for (const item of items) {
					if (item.id === targetId) {
						return [...ancestors, item.id]; // 包含所有上级+自身
					}
					if (item.children && item.children.length > 0) {
						const found = collectAncestorIds(item.children, targetId, [...ancestors, item.id]);
						if (found) return found;
					}
				}
				return null;
			};

			const ancestorIds = collectAncestorIds(menuItems, matchedItem.id);
			if (ancestorIds) {
				// 更新选中状态和展开状态（非折叠时才应用）
				const newLevelActiveNames = { 1: [], 2: [], 3: [] } as { [key: number]: string[] };
				const newLevelExpandNames = { 1: [], 2: [], 3: [] } as { [key: number]: string[] };

				ancestorIds.forEach((id, index) => {
					const level = index + 1;
					if (level <= 3) {
						// 关键：所有上级（含自身）均标记为激活
						newLevelActiveNames[level] = [id.toString()];
						// 非折叠状态下自动展开路径
						if (!isCollapsed) {
							newLevelExpandNames[level] = [id.toString()];
						}
					}
				});

				// 应用状态更新
				levelActiveNames = newLevelActiveNames;
				levelExpandNames = newLevelExpandNames;
			}
		}
	};
</script>

<!-- 收缩状态菜单渲染片段 -->
{#snippet CollapsedMenuSnippet(items: Option[])}
	{#each items as item,index (item.id)}
		<div
			class={`menu-item ${isOpen &&activeItemId === item.id && item.children && item.children.length>0 ? 'active' : ''}`}
			data-menu-id={item.id}
			onmouseenter={(e) => handleItemEnter(item,index, e)}
			onclick={(e) => handleCollapsedClick(item,index, e)}
			onkeydown={() => {}}
			role="button"
			tabindex="0"
			bind:this={triggerRefs[item.id]}
		>	
			<Icon src={item.iconName ? item.iconName : 'weather/moon'} size="15" />
		</div>
	{/each}
	<VerticalMenuPopover
		bind:triggerRef={triggerRefs[activeItemId!]}
		className={isOpen && items[activeItemIndex]?.children?.length ? 'is-expanded' : ''}
		{label}
		{accordion}
		options={items[activeItemIndex]?.children || []}
		parentItem={items[activeItemIndex] || {}}
		onClose={() => {
			isOpen = false;
		}}
	/>
{/snippet}

<!-- 主组件渲染 -->
<div class="vertical-menu" bind:this={menuContainerRef}>
	{#if !isCollapsed}
		<div class="menu-collapse-container" in:fade={{ duration: 300 }}>
			<Scrollbar scrollPadding={1} innerPadding="0 1px">
				<MenuSnippet
					items={menuItems}
					selectedLeafId={selectedLeafId}
					onItemClick={handleMenuItemClick}
					{label}
					isCollapsed={isCollapsed}
					level={1}
				/>
			</Scrollbar>
		</div>
	{:else}
		<div class="menu-list" in:fade={{ duration: 300 }}>
			<Scrollbar scrollPadding={1} innerPadding="0 1px">
				{@render CollapsedMenuSnippet(menuItems)}
			</Scrollbar>
		</div>
	{/if}
</div>

<style scoped lang="scss">
	.vertical-menu {
		width: 100%;
		height: calc(100% - 82px);
		position: relative;
	}
	.menu-collapse-container{
		height: 100%;
		overflow: hidden;
	}
	.menu-list {				
		height: 100%;
	}
	.menu-item{
		border-radius: 8px;
		height: 40px;
		display: flex;
		align-items: center;
		justify-content: center;
		cursor: pointer;

		&:hover:not(.active) { background-color: var(--color-fill); }
	}
</style>